package com.tamartech.greendb.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;

import org.apache.log4j.Logger;

import com.Ostermiller.util.CSVParser;
import com.Ostermiller.util.LabeledCSVParser;
import com.tamartech.greendb.data.Address;

// class to initially import Jonathan's spreadsheet. Unlikely ever to need it again
public class PostalVoterFilter_dedupe
{
    private static Logger logger = Logger.getLogger (PostalVoterFilter_dedupe.class);
    
    private static final int COL_REF1 = 0;
    private static final int COL_REF2 = 1;
    private static final int COL_ROW_TYPE = 2;
    private static final int COL_BIRTHDAY_18 = 3;
    private static final int COL_SURNAME = 4;
    private static final int COL_FIRST_NAMES = 5;
    private static final int COL_ADDRESS1 = 6;
    private static final int COL_ADDRESS2 = 7;
    private static final int COL_ADDRESS3 = 8;
    private static final int COL_ADDRESS4 = 9;
    private static final int COL_ADDRESS5 = 10;
    private static final int COL_ADDRESS6 = 11;
    private static final int POSTAL_COL = 22;
    
	public static void main(String[] args) throws Exception
	{
        File inFile = new File (args[0] + ".CSV");
        File newFile = new File (args[1] + ".CSV");
        File outFile = new File (args[1] + "-postalnew.csv");
	    
        Set<String> existing = new HashSet<String>();
        
        LabeledCSVParser csv = new LabeledCSVParser (new CSVParser (new FileInputStream (inFile)));
        LabeledCSVParser newcsv = new LabeledCSVParser (new CSVParser (new FileInputStream (newFile)));
        PrintWriter out = new PrintWriter (outFile);
        
        Address curAddress = new Address(); // i.e. initialise to empty one
        String names = "";
        
        for (;;)
        {
            String[] line = csv.getLine();
            
            if (line == null)
                break;
            
            if (line.length < 23 || !line[POSTAL_COL].trim().equals("Postal"))
                continue;
            
            String[] addressLines = new String [6];
            addressLines[0] = line[COL_ADDRESS1].trim();
            addressLines[1] = line[COL_ADDRESS2].trim();
            addressLines[2] = line[COL_ADDRESS3].trim();
            addressLines[3] = line[COL_ADDRESS4].trim();
            addressLines[4] = line[COL_ADDRESS5].trim();
            addressLines[5] = line[COL_ADDRESS6].trim();
            
            Address address = createAddress (addressLines);
            
            
            if (address.equals(curAddress))
            {
                names += " & " + line[COL_FIRST_NAMES].charAt(0) + " " + line[COL_SURNAME];
            }
            else
            {
                String addressString = curAddress.getAddress1() + "/" + curAddress.getAddress2() + "/" + curAddress.getAddress3();
                addressString = addressString.toLowerCase();
                
                existing.add(addressString);
                                
                curAddress = address;
                names = line[COL_FIRST_NAMES].charAt(0) + " " + line[COL_SURNAME];
            }
        }

        for (;;)
        {
            String[] line = newcsv.getLine();
            
            if (line == null)
                break;
            
            String name = line[18].trim() + " " + line[17].trim();
            String election = line[43];
            
            String[] addressLines = new String [6];
            addressLines[0] = line[21].trim();
            addressLines[1] = line[22].trim();
            addressLines[2] = line[23].trim();
            addressLines[3] = line[24].trim();
            addressLines[4] = line[25].trim();
            addressLines[5] = line[29].trim();
            
            Address address = createAddress (addressLines);
            
            String addressString = address.getAddress1() + "/" + address.getAddress2() + "/" + address.getAddress3();
            addressString = addressString.toLowerCase();

            if (!existing.contains(addressString))
            {
                StringBuffer outLine = new StringBuffer();
                
                outLine.append(toMixed(name) + "\t");
                outLine.append(toMixed (address.getAddress1()) + "\t");
                outLine.append(toMixed (address.getAddress2()) + "\t");
                outLine.append(toMixed (address.getAddress3()) + "\t");
                outLine.append(election + "\t");
                
                out.println (outLine.toString());
                
                existing.add(addressString);
            }
        }  
        
        csv.close();
        newcsv.close();
        out.close();

	}
	
    private static Address createAddress (String[] addressLines)
    {
        Address address = new Address();
        
        // reverse through the address to find the last populated line. That will be the postcode
        
        int postcodeIndex = addressLines.length - 1;
        
        for (;;)
        {
            if (postcodeIndex < 0 || addressLines[postcodeIndex].length() > 0)
                break;
                
            postcodeIndex--;
        }
        
        if (postcodeIndex >= 0)
        {
            address.setPostcode (addressLines[postcodeIndex]);
            
            if (postcodeIndex > 0)
                address.setAddress1(addressLines[0]);
            if (postcodeIndex > 1)
                address.setAddress2(addressLines[1]);
            if (postcodeIndex > 2)
                address.setAddress3(addressLines[2]);
            if (postcodeIndex > 3)
                address.setAddress4(addressLines[3]);
            if (postcodeIndex > 4)
                address.setAddress5(addressLines[4]);           
        }
        
        return address;
    }

    public static String toMixed(String input)
    {
        StringBuffer buff = new StringBuffer(input.length());
        boolean isWordStarted = false;
        for (int i = 0; i < input.length(); i++)
        {
            char c = input.charAt(i);
            if (Character.isLetter(c))
            {
                if (isWordStarted)
                    c = Character.toLowerCase(c);
                else

                    c = Character.toUpperCase(c);
                isWordStarted = true;
            }
            else
            {
                isWordStarted = false;
            }
            buff.append(c);
        }
        return buff.toString();
    }
} 